/*
=======================================================================

  Soldier - BOTS
  
=======================================================================
*/
#include "g_local.h"

#include "bots_game2cgame.h"

#include "bg_local.h"
#include "bots_local.h"
#include "bots_soldier.h"


void bots_updateClientData_soldier(gentity_t *self, bots_g2cg_soldier_t *p) {
	if (!self->client)
		return;

	BOTS_SETBIT(p->bits, self->client->qb_conquerMode,			BOTS_G2CG_SOLDIER_CONQUERMODE);
	BOTS_SETBIT(p->bits, self->client->qb_guide,				BOTS_G2CG_SOLDIER_GUIDE);
	BOTS_SETBIT(p->bits, self->client->qb_tagMode,				BOTS_G2CG_SOLDIER_TAG);

	//if (self->s.clientNum != BOTS_conquer_get((self->bots_team+1)%2)+1)
	if (self->s.clientNum != BOTS_conquer_get(self->bots_team==TEAM_RED?TEAM_BLUE:TEAM_RED))
		BOTS_SETBIT(p->bits, qfalse,		BOTS_G2CG_SOLDIER_CONQUERED);
	else
		BOTS_SETBIT(p->bits, qtrue,			BOTS_G2CG_SOLDIER_CONQUERED);

	// weapon modes? (not enough space in that structure to pack all modes in)
	p->weapons.gren1 = p->weapons.gren2 = p->weapons.grenademode = 0;
	p->weapons.weaponmode = self->client->weapontoggle?self->client->i_splitmode:0;
}

void G_ExplodeMissile( gentity_t *ent );

/////////////////////////////////////////////
//
// BOTS_guide_think
//
// This is the brains behind the guided rocket.  It goes wherever the soldier
// points.
// 
void BOTS_guide_think(gentity_t* self)
{
	gentity_t*	ent;
	vec3_t		forward;
	int			speed;

	if (!self->parent)
		return;
	ent = self->parent;

	if (!ent->client)
		return;

	// get the clients view direction
	AngleVectors (ent->client->ps.viewangles, forward, NULL, NULL);
	VectorNormalize(forward);

	// change the direction of the rocket
	VectorAdd(forward, self->movedir, forward);
	VectorNormalize(forward);
	VectorCopy(forward, self->movedir);
	vectoangles(forward, self->s.angles);

	// set the velocity
	speed = VectorLength(self->s.pos.trDelta);
	VectorScale(forward, speed, self->s.pos.trDelta);

	self->nextthink = level.time + FRAMETIME;

}

/////////////////////////////////////////////
//
// BOTS_conquer
//
// This toggles conquer mode for the soldier.  When a soldier has a capture
// pad conquered, the enemy can no longer capture there.
//
void BOTS_conquer(int clientNum)
{
	gentity_t* ent = g_entities + clientNum;

	// check to see if this class can use conquer
	if (ent->bots_class != BOTS_SOLDIER)
	{
		BOTS_cp_console(clientNum, "Only the Soldier can conquer.");
		return;
	}

	// check to see if we are level 2 or greater
	if (ent->client->pers.classlevel < 1)
	{
		BOTS_cp_console(clientNum, "You must be at least level 1 to conquer.");
		ent->client->weapontoggle = qfalse;
		return;
	}

	// toggle the state
	ent->client->qb_conquerMode = !ent->client->qb_conquerMode;

	// tell the client what he just did
	/*
	if (ent->client->qb_conquerMode)
		BOTS_cp_console( clientNum, "Conquer mode enabled.");
	else
	*/
	if (!ent->client->qb_conquerMode)
	{
		int conquer;
		int otherTeam;
		if (ent->bots_team == TEAM_RED)
			otherTeam = TEAM_BLUE;
		else
			otherTeam = TEAM_RED;

		conquer = BOTS_conquer_get(otherTeam);
		if (conquer == clientNum)
			BOTS_conquer_clear(otherTeam);
		
		/*
		BOTS_cp_console( clientNum, "Conquer mode disabled.");
		*/
	}
}

/////////////////////////////////////////////
//
// BOTS_splitnum
//
// Used in splitmode to determine the spread of your rockets.
// 
void BOTS_splitnum(int clientNum, int splitNum)
{
	gentity_t* ent = g_entities + clientNum;

	ent->client->i_splitmode = splitNum;
}

/////////////////////////////////////////////
//
// BOTS_splitmode
//
// This toggles splitmode rockets for the soldier.
// The multiple rockets are created in the function Weapon_RocketLauncher_Fire
// located in g_weapon.c
//
void BOTS_splitmode(int clientNum)
{
	gentity_t* ent = g_entities + clientNum;

	if (ent->bots_class == BOTS_SOLDIER)
	{
		// check to see if this class can use splitmode
		if (ent->bots_class != BOTS_SOLDIER)
		{
			BOTS_cp_console(clientNum, "Only the Soldier can use splitmode.");
			return;
		}

		// check to see if we are level 3 or greater
		if (ent->client->pers.classlevel < 3)
		{
			BOTS_cp_console(clientNum, "You must be at least level 3 for splitmode.");
			ent->client->weapontoggle = qfalse;
			return;
		}
	}
	else if (ent->bots_class == BOTS_CAPTAIN)
	{
		// check to see if we are level 4 
		if (ent->client->pers.classlevel < 4)
		{
			BOTS_cp_console(clientNum, "You must be level 4 for splitmode.");
			ent->client->weapontoggle = qfalse;
			return;
		}
	}
	else
		return;

	BOTS_weaponToggle(clientNum, ent->bots_class);
}

/////////////////////////////////////////////
//
// BOTS_guide
//
// This toggles guided rockets.
// 
void BOTS_guide(int clientNum)
{
	gentity_t* ent = g_entities + clientNum;

	// check to see if this class can use splitmode
	if (ent->bots_class != BOTS_SOLDIER)
	{
		BOTS_cp_console(clientNum, "Only the Soldier can use splitmode.");
		return;
	}

	// check to see if we are level 4 or greater
	if (ent->client->pers.classlevel < 4)
	{
		BOTS_cp_console(clientNum, "You must be at least level 4 for guided rockets.");
		ent->client->qb_guide = qfalse;
		return;
	}

	// toggle the state
	ent->client->qb_guide = !ent->client->qb_guide;

	// tell the client what he just did
	/*
	if (ent->client->qb_guide)
		BOTS_cp_console( clientNum, "Guided rockets enabled.");
	else
		BOTS_cp_console( clientNum, "Guided rockets disabled.");
	*/

	// turn splitmode off
	ent->client->weapontoggle	= qfalse;

	// turn tag cannon off
	ent->client->qb_tagMode		= qfalse;
	ent->tagEnt					= NULL;
}

/////////////////////////////////////////////
//
// BOTS_tag_think
//
// This is the think routine for the tag rockets.  They are homing rockets
// that zero in on the tagged target.  They do not zero in on random targets.
// 
void BOTS_tag_think(gentity_t* self)
{
	gentity_t*	ent;
	vec3_t		targetdir;
	vec3_t		targOrigin;
	int			speed;

	if (!self->parent)
		return;
	ent = self->parent;

	if (!ent->client)
		return;

	if (!ent->tagEntbck)
		return;

	VectorCopy(ent->tagEntbck->s.pos.trBase, targOrigin);
	targOrigin[2] += 0;
	VectorSubtract(targOrigin, ent->s.pos.trBase, targetdir);

	// target acquired, nudge our direction toward it
	VectorNormalize(targetdir);

	// change the scalar to make it turn tighter
	//VectorScale(targetdir, 10000, targetdir);
	//SnapVector( targetdir );


	// change the direction of the rocket
	VectorAdd(targetdir, self->movedir, targetdir);
	VectorNormalize(targetdir);
	VectorCopy(targetdir, self->movedir);
	vectoangles(targetdir, self->s.angles);

	// set the velocity
	//speed = VectorLength(self->s.pos.trDelta);
	speed = 1200;
	VectorScale(targetdir, speed, self->s.pos.trDelta);

	self->nextthink = level.time + FRAMETIME;
}

/////////////////////////////////////////////
//
// BOTS_fire_tag
//
// This sets fires the 'tag'.  It is a plasma shot that paints its target.
// the target is then fired at by multiple homing rockets.
// 
void BOTS_fire_tag(gentity_t* ent, vec3_t muzzle, vec3_t forward)
{
	gentity_t* tag;

	ent->client->ps.ammo[WP_ROCKET_LAUNCHER]++;

	tag = fire_plasma (ent, muzzle, forward);
	tag->damage = 1;
}

/////////////////////////////////////////////
//
// BOTS_tag
//
// This sets up the use of the tag cannon for soldiers
// 
void BOTS_tag (int clientNum)
{
	gentity_t* ent = g_entities + clientNum;

	// check to see if this class can use the tag cannon
	if (ent->bots_class != BOTS_SOLDIER)
	{
		BOTS_cp_console(clientNum, "Only the Soldier gets the tag cannon");
		return;
	}

	// check to see if we are level 2 or greater
	if (ent->client->pers.classlevel < 2)
	{
		BOTS_cp_console(clientNum, "You must be at least level 2 to use the tag cannon.");
		ent->client->qb_tagMode = qfalse;
		return;
	}

	ent->client->i_tagNum	= 0;
	ent->client->qb_tagMode = !ent->client->qb_tagMode;
	ent->client->i_tagTime	= level.time;

	/*
	if (ent->client->qb_tagMode)
		BOTS_cp_console(clientNum, "Tag Cannon enabled.");
	else
		BOTS_cp_console(clientNum, "Tag Cannon disabled.");
	*/

	ent->client->qb_guide	= qfalse;
	ent->client->weapontoggle = qfalse;
}

/////////////////////////////////////////////
//
// BOTS_SoldierCommands
//
// This will parse the passed cmd string and call to the correct functions.
// 
// RETURNS
//    qfalse : cmd is not a soldier command
//	  qtrue	 : cmd is a soldier command
//
qboolean BOTS_SoldierCommands(int clientNum, char* cmd)
{
	if (Q_stricmp (cmd, "split") == 0 )
	{
		BOTS_splitmode(clientNum);
		return qtrue;
	}
	if (Q_stricmp (cmd, "split1") == 0 )
	{
		BOTS_splitnum(clientNum, 1);
		return qtrue;
	}
	if (Q_stricmp (cmd, "split2") == 0 )
	{
		BOTS_splitnum(clientNum, 2);
		return qtrue;
	}
	if (Q_stricmp (cmd, "split3") == 0 )
	{
		BOTS_splitnum(clientNum, 3);
		return qtrue;
	}
	if (Q_stricmp (cmd, "conquer") == 0 )
	{
		BOTS_conquer(clientNum);
		return qtrue;
	}
	if (Q_stricmp (cmd, "guide") == 0 )
	{
		BOTS_guide(clientNum);
		return qtrue;
	}
	if (Q_stricmp (cmd, "tag") == 0)
	{
		BOTS_tag(clientNum);
		return qtrue;
	}

	return qfalse;
}

/////////////////////////////////////////////
//
// BOTS_ClientThink_soldier
//
// Soldier think routine.  Called once for each client think if
// the client is a soldier.
//
void BOTS_ClientThink_soldier(gentity_t* ent)
{
	if (ent->health <= 0)
		return;

	if (ent->client->pers.classlevel < 2)
		if (ent->client->weapontoggle)
		{
			ent->client->weapontoggle = qfalse;
		}
	if (ent->client->pers.classlevel < 4)
		if (ent->client->qb_guide)
		{
			ent->client->qb_guide = qfalse;
		}

	if (ent->client->i_tagNum == 5)
	{
		ent->tagEnt = NULL;
		ent->client->i_tagNum = 0;
	}
	
	// fire 6 rockets very fast
	if (ent->client->qb_tagMode && ent->tagEnt)
	{
		if (ent->client->i_tagTime < level.time)
		{
			if (ent->client->ps.ammo[WP_ROCKET_LAUNCHER] > 0)
			{
				// subtract ammo - fire weapon will not do it alone
				ent->client->ps.ammo[WP_ROCKET_LAUNCHER]--;

				ent->client->ps.weaponTime = 0;
				FireWeapon(ent);
				ent->client->i_tagTime = level.time + 200;
				ent->client->i_tagNum++;
			}
			else
			{
				ent->tagEnt = NULL;
				ent->client->qb_tagMode = qfalse;
			}
		}
	}// tag rockets

}
